home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / c / minigl.lha / MiniGL / demos / rasonly.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-03-27  |  7.0 KB  |  336 lines

  1. /*
  2.  * rasonly.c -
  3.  *  Demonstrates the use of OpenGL for rasterization-only, with
  4.  *  perspective-correct texture mapping.
  5.  *
  6.  * Michael I. Gold <gold@berkelium.com>
  7.  * Silicon Graphics Computer Systems, May 1997
  8.  * NVIDIA Corporation, March 1999
  9.  *
  10.  * Since current low-end 3D accelerators support only rasterization in
  11.  * hardware, a number of developers have expressed interested in using
  12.  * OpenGL as an interface to rasterization hardware while retaining
  13.  * control of transformations and lighting in the application code.
  14.  * Many OpenGL implementations detect and optimize for identity xforms,
  15.  * so this approach is entirely reasonable.
  16.  *
  17.  * Setting up rasterization-only is fairly straightforward.  The projection
  18.  * matrix is set up as a one-to-one mapping between eye and clip coordinates,
  19.  * and the modelview matrix is set up as identity, e.g. object coordinates
  20.  * map directly to eye coordinates.  This can be achieved as follows:
  21.  *
  22.  *  glMatrixMode(GL_PROJECTION);
  23.  *  glLoadIdentity();
  24.  *  glOrtho(0.0f, (GLfloat) width, 0.0f, (GLfloat) height, 0.0f, 1.0f);
  25.  *  glMatrixMode(GL_MODELVIEW);
  26.  *  glLoadIdentity();
  27.  *  glViewport(0, 0, width, height);
  28.  *      glDepthRange(0.0f, 1.0f);
  29.  *
  30.  * where (width, height) represent the window dimensions.
  31.  *
  32.  * Now transformed geometry may be specified directly through the standard
  33.  * interfaces (e.g. glVertex*()).  The only tricky part that remains is
  34.  * specifying texture coordinates such that perspective correction may
  35.  * occur.  The answer is to use glTexCoord4*(), and perform the perspective
  36.  * divide on the texture coordinates directly.
  37.  *
  38.  * Changes -
  39.  *
  40.  * 3/14/1999
  41.  * Fixed glOrtho z-mapping, was [-1,1], should have been [0,1].
  42.  * Explicitly set glDepthRange to [0,1].
  43.  * Thanks to Jonathon Wolfe <jwolfe@lclark.edu> for the bug report!
  44.  */
  45.  
  46. /*
  47.  * Adapted to MiniGL
  48.  */
  49.  
  50. #include <stdio.h>
  51. #include <string.h>
  52. #include <stdlib.h>
  53. #include <mgl/gl.h>
  54. #include <assert.h>
  55.  
  56.  
  57. GLboolean motion = GL_TRUE;
  58. void Motion(void);
  59.  
  60. /* Matrices */
  61. GLfloat rot = 0.0f;
  62. GLfloat ModelView[16];
  63. GLfloat Projection[16];
  64. GLfloat Viewport[4];
  65.  
  66. /* Sample geometry */
  67. GLfloat quadV[][4] = {
  68.     { -1.0f, 0.0f, -1.0f, 1.0f },
  69.     {  1.0f, 0.0f, -1.0f, 1.0f },
  70.     {  1.0f, 0.5f, -0.2f, 1.0f },
  71.     { -1.0f, 0.5f, -0.2f, 1.0f },
  72. };
  73.  
  74. GLfloat quadC[][3] = {
  75.     { 1.0f, 0.0f, 0.0f },
  76.     { 0.0f, 1.0f, 0.0f },
  77.     { 0.0f, 0.0f, 1.0f },
  78.     { 1.0f, 1.0f, 1.0f },
  79. };
  80.  
  81. GLfloat quadT[][2] = {
  82.     { 0.0f, 0.0f },
  83.     { 0.0f, 1.0f },
  84.     { 1.0f, 1.0f },
  85.     { 1.0f, 0.0f },
  86. };
  87.  
  88. /*********************************************************************
  89.  * Utility functions
  90.  */
  91.  
  92. int texWidth = 128;
  93. int texHeight = 128;
  94.  
  95. /* Create and download the application texture map */
  96. static void
  97. setCheckedTexture(void)
  98. {
  99.     int texSize;
  100.     void *textureBuf;
  101.     GLubyte *p;
  102.     int i,j;
  103.  
  104.     /* malloc for rgba as worst case */
  105.     texSize = texWidth*texHeight*4;
  106.  
  107.     textureBuf = malloc(texSize);
  108.     if (NULL == textureBuf) return;
  109.  
  110.     p = (GLubyte *)textureBuf;
  111.     for (i=0; i < texWidth; i++) {
  112.         for (j=0; j < texHeight; j++) {
  113.             if ((i ^ j) & 8) {
  114.                 p[0] = 0xff; p[1] = 0xff; p[2] = 0xff; p[3] = 0xff;
  115.             } else {
  116.                 p[0] = 0x08; p[1] = 0x08; p[2] = 0x08; p[3] = 0xff;
  117.             }
  118.             p += 4;
  119.         }
  120.     }
  121.  
  122.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight,
  123.             0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuf);
  124.  
  125.     free(textureBuf);
  126. }
  127.  
  128. /* Perform one transform operation */
  129. static void
  130. Transform(GLfloat *matrix, GLfloat *in, GLfloat *out)
  131. {
  132.     int ii;
  133.  
  134.     for (ii=0; ii<4; ii++) {
  135.         out[ii] =
  136.             in[0] * matrix[0*4+ii] +
  137.             in[1] * matrix[1*4+ii] +
  138.             in[2] * matrix[2*4+ii] +
  139.             in[3] * matrix[3*4+ii];
  140.     }
  141. }
  142.  
  143. /* Transform a vertex from object coordinates to window coordinates.
  144.  * Lighting is left as an exercise for the reader.
  145.  */
  146. static void
  147. DoTransform(GLfloat *in, GLfloat *out)
  148. {
  149.     GLfloat tmp[4];
  150.     GLfloat invW;   /* 1/w */
  151.  
  152.     /* Modelview xform */
  153.     Transform(ModelView, in, tmp);
  154.  
  155.     /* Lighting calculation goes here! */
  156.  
  157.     /* Projection xform */
  158.     Transform(Projection, tmp, out);
  159.  
  160.     if (out[3] == 0.0f) /* do what? */
  161.         return;
  162.  
  163.     invW = 1.0f / out[3];
  164.  
  165.     /* Perspective divide */
  166.     out[0] *= invW;
  167.     out[1] *= invW;
  168.     out[2] *= invW;
  169.  
  170.     /* Map to 0..1 range */
  171.     out[0] = out[0] * 0.5f + 0.5f;
  172.     out[1] = out[1] * 0.5f + 0.5f;
  173.     out[2] = out[2] * 0.5f + 0.5f;
  174.  
  175.     /* Map to viewport */
  176.     out[0] = out[0] * Viewport[2] + Viewport[0];
  177.     out[1] = out[1] * Viewport[3] + Viewport[1];
  178.  
  179.     /* Store inverted w for performance */
  180.     out[3] = invW;
  181. }
  182.  
  183. /*********************************************************************
  184.  * Application code begins here
  185.  */
  186.  
  187. /* For the sake of brevity, I'm use OpenGL to compute my matrices. */
  188. void UpdateModelView(void)
  189. {
  190.     glPushMatrix();
  191.     glLoadIdentity();
  192.     gluLookAt(0.0f, 1.0f, -4.0f,
  193.           0.0f, 0.0f, 0.0f,
  194.           0.0f, 1.0f, 0.0f);
  195.     glRotatef(rot, 0.0f, 1.0f, 0.0f);
  196.     /* Retrieve the matrix */
  197.     glGetFloatv(GL_MODELVIEW_MATRIX, ModelView);
  198.     glPopMatrix();
  199. }
  200.  
  201. void InitMatrices(void)
  202. {
  203.     /* Calculate projection matrix */
  204.     glMatrixMode(GL_PROJECTION);
  205.     glPushMatrix();
  206.     glLoadIdentity();
  207.     gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);
  208.     /* Retrieve the matrix */
  209.     glGetFloatv(GL_PROJECTION_MATRIX, Projection);
  210.     glPopMatrix();
  211.     glMatrixMode(GL_MODELVIEW);
  212.  
  213.     UpdateModelView();
  214. }
  215.  
  216. void Init()
  217. {
  218.     glClearColor(0.2f, 0.2f, 0.6f, 1.0f);
  219.  
  220.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  221.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  222.     glEnable(GL_TEXTURE_2D);
  223.     setCheckedTexture();
  224.  
  225.     InitMatrices();
  226. }
  227.  
  228. void Redraw(void)
  229. {
  230.     GLfloat tmp[4];
  231.     int ii;
  232.  
  233.     mglLockDisplay();
  234.  
  235.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  236.  
  237. //        glBegin(GL_QUADS);
  238.     glBegin(GL_TRIANGLE_FAN);
  239.  
  240.     for (ii = 0; ii < 4; ii++) {
  241.  
  242.         /* Transform a vertex from object to window coordinates.
  243.          * 1/w is returned as tmp[3] for perspective-correcting
  244.          * the texture coordinates.
  245.          */
  246.         DoTransform(quadV[ii], tmp);
  247.  
  248.         /* Ideally the colors will be computed by the lighting equation,
  249.          * but I've hard-coded values for this example.
  250.          */
  251.         glColor3fv(quadC[ii]);
  252.  
  253.         /* Scale by 1/w (stored in tmp[3]) */
  254.         glTexCoord4f(quadT[ii][0] * tmp[3],
  255.                  quadT[ii][1] * tmp[3], 0.0f, tmp[3]);
  256.  
  257.         /* Note I am using Vertex3, not Vertex4, since we have already
  258.          * performed the perspective divide.
  259.          */
  260.         glVertex3fv(tmp);
  261.     }
  262.  
  263.     glEnd();
  264.  
  265.     mglSwitchDisplay();
  266.  
  267.     if (motion)
  268.         Motion();
  269.  
  270. }
  271.  
  272. void Motion(void)
  273. {
  274.     rot += 3.0f;
  275.     if (rot >= 360.0f) rot -= 360.0f;
  276.     UpdateModelView();
  277. }
  278.  
  279.  
  280. void Key(char key)
  281. {
  282.     switch (key) {
  283.         case 27:
  284.             mglExit();
  285.             break;
  286.         case 'm':
  287.             motion = !motion;
  288.             break;
  289.     }
  290. }
  291.  
  292.  
  293. void Reshape(int width, int height)
  294. {
  295.     glMatrixMode(GL_PROJECTION);
  296.     glLoadIdentity();
  297.     glOrtho(0.0f, (GLfloat) width, 0.0f, (GLfloat) height, -1.0f, 1.0f);
  298.  
  299.     glMatrixMode(GL_MODELVIEW);
  300.     glLoadIdentity();
  301.  
  302.     glViewport(0, 0, width, height);
  303.     glDepthRange(0.0f, 1.0f);
  304.  
  305.     Viewport[0] = Viewport[1] = 0.0f;
  306.     Viewport[2] = (GLfloat) width;
  307.     Viewport[3] = (GLfloat) height;
  308. }
  309.  
  310. int
  311. #ifdef WIN32
  312. __cdecl
  313. #endif
  314. main(int argc, char *argv[])
  315. {
  316.     int width = 640, height = 480;
  317.     char *t;
  318.  
  319.     mglChooseWindowMode(GL_TRUE);
  320.     MGLInit();
  321.     mglCreateContext(0,0,width,height);
  322.  
  323.     Init();
  324.     Reshape(width, height);
  325.  
  326.     mglKeyFunc(Key);
  327.     mglIdleFunc(Redraw);
  328.     mglMainLoop();
  329.  
  330.     mglDeleteContext();
  331.     MGLTerm();
  332.  
  333.  
  334.     return 0;
  335. }
  336.